﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Scheduler;

namespace WakeApp
{
    public partial class AggiungiSveglia : PhoneApplicationPage
    {
        private bool[] giorni;
        private BitmapImage imageON = new BitmapImage(new Uri("images/toggleon.png", UriKind.Relative));
        private BitmapImage imageOFF = new BitmapImage(new Uri("images/toggleoff.png", UriKind.Relative));

        //storage dell'applicazione
        private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

        //nome degli allarmi nello scheduler
        private string nextAlarmName = "WakeUpAlarm";

        public AggiungiSveglia()
        {
            InitializeComponent();

            giorni = new bool[7];
            giorni.Initialize();

            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;

            Lun.Background = disattivato;
            Mar.Background = disattivato;
            Mer.Background = disattivato;
            Gio.Background = disattivato;
            Ven.Background = disattivato;
            Sab.Background = disattivato;
            Dom.Background = disattivato;
            Lun.BorderThickness = new System.Windows.Thickness(0);
            Mar.BorderThickness = new System.Windows.Thickness(0);
            Mer.BorderThickness = new System.Windows.Thickness(0);
            Gio.BorderThickness = new System.Windows.Thickness(0);
            Ven.BorderThickness = new System.Windows.Thickness(0);
            Sab.BorderThickness = new System.Windows.Thickness(0);
            Dom.BorderThickness = new System.Windows.Thickness(0);
        }

        private void ButtonAdd_Click(object sender, RoutedEventArgs e)
        {
            //raccolgo i valori e creo la stringa ora:min|giorni|on da inserire nel txt
            System.DateTime newTime = (System.DateTime)timePicker1.Value;
            String s = newTime.Hour + ":" + newTime.Minute + "|";
            foreach (bool b in giorni)
            {
                if (b)//true
                    s = s + "1";
                else//false
                    s = s + "0";
            }//foreach

            //controllo in giornata
            string[] res = s.Split(':');
            int ora = int.Parse(res[0]);
            res = res[1].Split('|');
            int min = int.Parse(res[0]);
            string settimana = res[1];

            if (settimana == "0000000")
            {
                int indexOfToday = indexOfWeek();
                int annoAttuale = DateTime.Now.Year;
                int meseAttuale = DateTime.Now.Month;
                int giornoAttuale = DateTime.Now.Day;
                int oraAttuale = DateTime.Now.Hour;
                int minAttuale = DateTime.Now.Minute;

                //controllo l'ora
                if (ora > oraAttuale || (ora == oraAttuale && min > minAttuale))//sveglia corretta
                {
                    //la sveglia è oggi
                    settimana="";
                    
                    for (int i = 0; i < 7; i++)
                        if (i == indexOfToday)
                            settimana = settimana + '1';
                        else
                            settimana=settimana+'0';
                }
                else
                {
                    //la sveglia è domani
                    settimana = "";
                    int index = (indexOfToday + 1) % 7;

                    for (int i = 0; i < 7; i++)
                        if (i == index)
                            settimana = settimana + '1';
                        else
                            settimana = settimana + '0';
                }

            }

            s = ora + ":" + min + "|" + settimana;

            bool trovato = false;

            if (appSettings.Contains(s))//se già presente
            {
                appSettings[s] = "on";//sovrascrivo e setto ad on
            }
            else//altrimenti, controllo se esiste una simile
            {
                foreach (string key in appSettings.Keys)
                {
                    string[] ris = key.Split('|');
                    if (ris[0] == s.Split('|')[0])//se hanno la stessa ora
                    {
                        MessageBox.Show("There is another Alarm with the same time.");
                        trovato = true;
                    }
                }

                if (!trovato)
                    appSettings.Add(s, "on");//creo nuova voce
            }

            ModifyAlarm();

            //torno alla pagina MainPage e refresh
            NavigationService.GoBack();
        }//ButtonAdd_Click

        private void Lun_Checked(object sender, RoutedEventArgs e)
        {
            giorni[0] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Lun.Background=attivato;
            Lun.BorderThickness= new System.Windows.Thickness(0);
            Lun.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Mar_Checked(object sender, RoutedEventArgs e)
        {
            giorni[1] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Mar.Background = attivato;
            Mar.BorderThickness = new System.Windows.Thickness(0);
            Mar.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Mer_Checked(object sender, RoutedEventArgs e)
        {
            giorni[2] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Mer.Background = attivato;
            Mer.BorderThickness = new System.Windows.Thickness(0);
            Mer.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Gio_Checked(object sender, RoutedEventArgs e)
        {
            giorni[3] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Gio.Background = attivato;
            Gio.BorderThickness = new System.Windows.Thickness(0);
            Gio.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Ven_Checked(object sender, RoutedEventArgs e)
        {
            giorni[4] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Ven.Background = attivato;
            Ven.BorderThickness = new System.Windows.Thickness(0);
            Ven.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Sab_Checked(object sender, RoutedEventArgs e)
        {
            giorni[5] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Sab.Background = attivato;
            Sab.BorderThickness = new System.Windows.Thickness(0);
            Sab.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Dom_Checked(object sender, RoutedEventArgs e)
        {
            giorni[6] = true;
            ImageBrush attivato = new ImageBrush();
            ImageSource src = imageON;
            attivato.ImageSource = src;
            Dom.Background = attivato;
            Dom.BorderThickness = new System.Windows.Thickness(0);
            Dom.Foreground = new SolidColorBrush(Colors.White);
        }

        private void Lun_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[0] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Lun.Background = disattivato;
        }

        private void Mar_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[1] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Mar.Background = disattivato;
        }

        private void Mer_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[2] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Mer.Background = disattivato;
        }

        private void Gio_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[3] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Gio.Background = disattivato;
        }

        private void Ven_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[4] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Ven.Background = disattivato;
        }

        private void Sab_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[5] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Sab.Background = disattivato;
        }

        private void Dom_Unchecked(object sender, RoutedEventArgs e)
        {
            giorni[6] = false;
            ImageBrush disattivato = new ImageBrush();
            ImageSource src = imageOFF;
            disattivato.ImageSource = src;
            Dom.Background = disattivato;
        }

        private int indexOfWeek()
        {
            string s = DateTime.Now.DayOfWeek.ToString();
            switch (s)
            {
                case "Monday": return 0;
                case "Tuesday": return 1;
                case "Wednesday": return 2;
                case "Thursday": return 3;
                case "Friday": return 4;
                case "Saturday": return 5;
                case "Sunday": return 6;

                default: return 0;
            }
        }

        private DateTime fromStringToDateTime(string s)
        {
            string[] ris = s.Split(':');
            int ora = int.Parse(ris[0]);
            ris = ris[1].Split('|');
            int min = int.Parse(ris[0]);
            string settimana = ris[1];

            int indexOfToday = indexOfWeek();
            int annoAttuale = DateTime.Now.Year;
            int meseAttuale = DateTime.Now.Month;
            int giornoAttuale = DateTime.Now.Day;
            int oraAttuale = DateTime.Now.Hour;
            int minAttuale = DateTime.Now.Minute;

            bool trovato = false;

            if (settimana == "0000000")//sveglia in giornata
            {
                //controllo l'ora
                if (ora > oraAttuale || (ora == oraAttuale && min > minAttuale))//sveglia corretta
                {
                    //la sveglia è oggi
                    return new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                }
                else
                {
                    //la sveglia è domani
                    DateTime temp = new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                    return new DateTime(temp.Ticks + TimeSpan.TicksPerDay);
                }
            }
            else//ha almeno un 1 in settimana
            {
                if ((settimana[indexOfToday] == '1') && (ora > oraAttuale || (ora == oraAttuale && min > minAttuale)))//la sveglia è oggi
                {
                    return new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                }
                else//la sveglia non è oggi
                {
                    int i = indexOfToday + 1;//parto da domani

                    while (!trovato)
                    {

                        if (settimana[i] == '1')
                        {
                            trovato = true;
                            int numDay = (((indexOfToday + i) % 7) + 1);

                            DateTime temp = new DateTime(annoAttuale, meseAttuale, giornoAttuale, ora, min, 0);
                            return new DateTime(temp.Ticks + TimeSpan.TicksPerDay * numDay);
                        }

                        if (i == indexOfToday)
                            break;

                        i = (i + 1) % 7;
                    }

                    MessageBox.Show("an unknow error has accured");//impossibile to happen
                }
            }

            return new DateTime();//impossibile to happen
        }//fromStringToDateTime

        private void ModifyAlarm()
        {
            if (appSettings.Contains("nextAlarm"))
            {
                appSettings.Remove("nextAlarm");

                //eliminare vecchie sveglie, se le trovo
                for (int i = 0; i < 20; i++)
                    if (ScheduledActionService.Find(nextAlarmName + i.ToString()) != null)//ho trovato una sveglia con questo nome
                    {
                        ScheduledActionService.Remove(nextAlarmName + i.ToString());//la rimuovo
                    }
            }

            if (appSettings.Count > 0)//esiste almeno una sveglia
            {
                DateTime min;
                string minKey = "";
                DateTime temp;

                foreach (string key in appSettings.Keys)//prendo la prima
                {

                    if (appSettings[key].ToString() == "on")
                    {
                        minKey = key;//salvo la chiave
                        break;
                    }
                }

                if (minKey != "")//almeno una a on
                {
                    min = fromStringToDateTime(minKey);

                    foreach (string key in appSettings.Keys)//mette in min la sveglia più prossima
                    {
                        if (appSettings[key].ToString() == "on")//guardo quelle attive
                        {
                            temp = fromStringToDateTime(key);

                            if (temp.Ticks < min.Ticks)
                            {
                                min = temp;//salvo il datetime
                                minKey = key;//e la chiave relativa alla sveglia
                            }
                        }
                    }

                    if (appSettings.Contains("nextAlarm"))//ho almeno un'altra sveglia dentro
                    {
                        appSettings["nextAlarm"] = min;//la sostituisco con la nuova prossima sveglia
                    }
                    else //se non c'è nulla è la prima sveglia
                    {
                        appSettings.Add("nextAlarm", min);//l'aggiungo
                    }

                    
                    //eliminare vecchie sveglie, se le trovo
                    for (int i = 0; i < 20; i++)
                        if (ScheduledActionService.Find(nextAlarmName + i.ToString()) != null)//ho trovato una sveglia con questo nome
                        {
                            ScheduledActionService.Remove(nextAlarmName + i.ToString());//la rimuovo
                        }

                    for (int i = 0; i < 20; i++)
                    {
                        DateTime supl = new DateTime(min.Ticks + (TimeSpan.TicksPerMinute * i));

                        Alarm sv = new Alarm(nextAlarmName + i.ToString());
                        sv.Content = "it's time to wake up my dear.";
                        sv.Sound = new Uri("Audio/elisa.wav", UriKind.Relative);
                        sv.BeginTime = supl;

                        ScheduledActionService.Add(sv);
                    }
                }
            }

        }//ModifyAlarm

    }//aggiungisveglia
}